# -*- coding:utf-8 -*-

import ctypes
import traceback

DEBUG = 1

N_FLAG = 0x80
V_FLAG = 0x40
U_FLAG = 0x20
B_FLAG = 0x10
D_FLAG = 0x08
I_FLAG = 0x04
Z_FLAG = 0x02
C_FLAG = 0x01

FCEU_IQEXT    = 0x001
FCEU_IQEXT2   = 0x002
FCEU_IQRESET  = 0x020
FCEU_IQNMI2   = 0x040  # Delayed NMI, gets converted to *_IQNMI
FCEU_IQNMI    = 0x080
FCEU_IQDPCM   = 0x100
FCEU_IQFCOUNT = 0x200
FCEU_IQTEMP   = 0x800

class X6502:
    def __init__(self, getPhysicalAddress, read, write):
        self.getPhysicalAddress = getPhysicalAddress
        self.print_mapping = True # False
        self.debug_count = -1
        self.print_layers = 0
        self.print_IRQ_layers = None
        self.count_stack = [0]
        self.limit_count = 1000000
        self.IRQ_PC = 0x0000

        self.PC = 0
        self.A = 0
        self.X = 0
        self.Y = 0
        self.S = 0xFD
        self.P = 0
        self.IRQlow = 0  # FCEU_IQRESET
        self.RAM = bytearray(0x800)
        self.ARead = read
        self.BWrite = write

        self.ZNTable = [0] * 256
        for i in range(256):
            if not i:
                self.ZNTable[i] = Z_FLAG
            elif i & 0x80:
                self.ZNTable[i] = N_FLAG
            else:
                self.ZNTable[i] = 0
        self.opcode_table = [
            self.opcode_00, self.opcode_01, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_05, self.opcode_06, self.opcode_unknown, self.opcode_08, self.opcode_09, self.opcode_0A, self.opcode_unknown, self.opcode_unknown, self.opcode_0D, self.opcode_0E, self.opcode_unknown,
            self.opcode_10, self.opcode_11, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_15, self.opcode_16, self.opcode_unknown, self.opcode_18, self.opcode_19, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_1D, self.opcode_1E, self.opcode_unknown,
            self.opcode_20, self.opcode_21, self.opcode_unknown, self.opcode_unknown, self.opcode_24, self.opcode_25, self.opcode_26, self.opcode_unknown, self.opcode_28, self.opcode_29, self.opcode_2A, self.opcode_unknown, self.opcode_2C, self.opcode_2D, self.opcode_2E, self.opcode_unknown,
            self.opcode_30, self.opcode_31, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_35, self.opcode_36, self.opcode_unknown, self.opcode_38, self.opcode_39, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_3D, self.opcode_3E, self.opcode_unknown,
            self.opcode_40, self.opcode_41, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_45, self.opcode_46, self.opcode_unknown, self.opcode_48, self.opcode_49, self.opcode_4A, self.opcode_unknown, self.opcode_4C, self.opcode_4D, self.opcode_4E, self.opcode_unknown,
            self.opcode_50, self.opcode_51, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_55, self.opcode_56, self.opcode_unknown, self.opcode_58, self.opcode_59, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_5D, self.opcode_5E, self.opcode_unknown,
            self.opcode_60, self.opcode_61, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_65, self.opcode_66, self.opcode_unknown, self.opcode_68, self.opcode_69, self.opcode_6A, self.opcode_unknown, self.opcode_6C, self.opcode_6D, self.opcode_6E, self.opcode_unknown,
            self.opcode_70, self.opcode_71, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_75, self.opcode_76, self.opcode_unknown, self.opcode_78, self.opcode_79, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_7D, self.opcode_7E, self.opcode_unknown,
            self.opcode_unknown, self.opcode_81, self.opcode_unknown, self.opcode_unknown, self.opcode_84, self.opcode_85, self.opcode_86, self.opcode_unknown, self.opcode_88, self.opcode_unknown, self.opcode_8A, self.opcode_unknown, self.opcode_8C, self.opcode_8D, self.opcode_8E, self.opcode_unknown,
            self.opcode_90, self.opcode_91, self.opcode_unknown, self.opcode_unknown, self.opcode_94, self.opcode_95, self.opcode_96, self.opcode_unknown, self.opcode_98, self.opcode_99, self.opcode_9A, self.opcode_unknown, self.opcode_unknown, self.opcode_9D, self.opcode_unknown, self.opcode_unknown,
            self.opcode_A0, self.opcode_A1, self.opcode_A2, self.opcode_unknown, self.opcode_A4, self.opcode_A5, self.opcode_A6, self.opcode_unknown, self.opcode_A8, self.opcode_A9, self.opcode_AA, self.opcode_unknown, self.opcode_AC, self.opcode_AD, self.opcode_AE, self.opcode_unknown,
            self.opcode_B0, self.opcode_B1, self.opcode_unknown, self.opcode_unknown, self.opcode_B4, self.opcode_B5, self.opcode_B6, self.opcode_unknown, self.opcode_B8, self.opcode_B9, self.opcode_BA, self.opcode_unknown, self.opcode_BC, self.opcode_BD, self.opcode_BE, self.opcode_unknown,
            self.opcode_C0, self.opcode_C1, self.opcode_unknown, self.opcode_unknown, self.opcode_C4, self.opcode_C5, self.opcode_C6, self.opcode_unknown, self.opcode_C8, self.opcode_C9, self.opcode_CA, self.opcode_unknown, self.opcode_CC, self.opcode_CD, self.opcode_CE, self.opcode_unknown,
            self.opcode_D0, self.opcode_D1, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_D5, self.opcode_D6, self.opcode_unknown, self.opcode_D8, self.opcode_D9, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_DD, self.opcode_DE, self.opcode_unknown,
            self.opcode_E0, self.opcode_E1, self.opcode_unknown, self.opcode_unknown, self.opcode_E4, self.opcode_E5, self.opcode_E6, self.opcode_unknown, self.opcode_E8, self.opcode_E9, self.opcode_EA, self.opcode_unknown, self.opcode_EC, self.opcode_ED, self.opcode_EE, self.opcode_unknown,
            self.opcode_F0, self.opcode_F1, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_F5, self.opcode_F6, self.opcode_unknown, self.opcode_F8, self.opcode_F9, self.opcode_unknown, self.opcode_unknown, self.opcode_unknown, self.opcode_FD, self.opcode_FE, self.opcode_unknown,
        ]

    def run(self):
        if self.IRQ_PC:
            if not (self.P & I_FLAG):
                self.PUSH(self.PC>>8)
                self.PUSH(self.PC)
                self.PUSH((self.P&~B_FLAG)|(U_FLAG))
                self.P |= I_FLAG
                self.PC = self.IRQ_PC
                self.IRQ_PC = 0x0000
                # self.print_IRQ_layers = 1
        # if self.IRQlow:
        #     if self.IRQlow & FCEU_IQRESET:
        #         self.PC = self.RdMem(0xFFFC)
        #         self.PC |= self.RdMem(0xFFFD) << 8
        #         self.P = I_FLAG
        #         self.IRQlow &= ~FCEU_IQRESET
        #     elif self.IRQlow & FCEU_IQNMI2:
        #         self.IRQlow &= ~FCEU_IQNMI2
        #         self.IRQlow |= FCEU_IQNMI
        #     elif self.IRQlow & FCEU_IQNMI:
        #         self.PUSH(self.PC>>8)
        #         self.PUSH(self.PC)
        #         self.PUSH((self.P&~B_FLAG)|(U_FLAG))
        #         self.P |= I_FLAG
        #         self.PC = self.RdMem(0xFFFA)
        #         self.PC |= self.RdMem(0xFFFB) << 8
        #         self.IRQlow &= ~FCEU_IQNMI
        #     else:
        #         if not (self.P & I_FLAG):
        #             self.PUSH(self.PC>>8)
        #             self.PUSH(self.PC)
        #             self.PUSH((self.P&~B_FLAG)|(U_FLAG))
        #             self.P |= I_FLAG
        #             self.PC = self.RdMem(0xFFFE)
        #             self.PC |= self.RdMem(0xFFFF) << 8
        #     self.IRQlow &= ~FCEU_IQTEMP

        pc = self.PC
        physical_address = self.getPhysicalAddress(pc)
        # if physical_address in (0x00E9F60F,):  # 开始打印改这里
        #     self.debug_count = 0
        #     self.print_layers = 1
        # if physical_address == 0x00E95FDE:  # 打印print_mapping，修改此处
        #     self.print_mapping = True
        # if physical_address == 0x00E8449B and self.print_mapping:  # 勿改
        #     print('print_mapping')
        #     return 1
        if physical_address == 0xE882F6: # 0xD2F6:  # 记录调用banked里面的函数，勿改
            self.count_stack.append(0)
            self.print_layers -= 1
        if self.debug_count >= 0:
            self.debug_count += 1
        if self.debug_count >= 1000:
            print('debug_count overflow')
            return 1  # 找到需要的指令后面的xx条指令
        prefix = '[{:08X}]{:04X} [{:02X} {:02X} {:02X}]:'.\
            format(physical_address, pc,
                   self.RdMem(pc), self.RdMem(pc+1), self.RdMem(pc+2))
        opcode = self.RdMem(self.PC)
        self.PC += 1

        try:
            self.opcode_table[opcode](prefix, pc)
        except Exception as e:
            traceback.print_exc()
            return 1

        # self.count_stack[-1] += 1
        # if self.count_stack[-1] > self.limit_count:
        #     print('count[{}] beyond {}'.format(self.count_stack[-1], self.limit_count))
        #     return 1  # 使程序退出
        return 0

    def print(self, *args, **kwargs):
        if self.print_layers > 0 or self.print_IRQ_layers:
            print(*args, **kwargs)

    def RdMem(self, addr, direct=False):
        addr &= 0xFFFF
        return self.ARead(addr, direct)

    def WrMem(self, addr, data):
        addr &= 0xFFFF
        self.BWrite(addr, data)

    def RdRAM(self, addr):
        # addr &= 0xFFFF
        # return self.RAM[addr]
        return self.ARead(addr)

    def WrRAM(self, addr, data):
        # addr &= 0xFFFF
        # self.RAM[addr] = 0xFF & data
        self.BWrite(addr, data)

    def PUSH(self, data):
        # print('push: 0x{:02X}'.format(data))
        self.WrRAM(0x100+self.S, data)
        self.S -= 1

    def POP(self):
        self.S += 1
        data = self.RdRAM(0x100+self.S)
        # print('pop: 0x{:02X}'.format(data))
        return data

    def X_ZN(self, zort):
        self.P &= ~(Z_FLAG|N_FLAG)
        self.P |= self.ZNTable[zort]

    def X_ZNT(self, zort):
        self.P |= self.ZNTable[zort]

    def JR(self, cond):
        if cond:
            disp = ctypes.c_int8(self.RdMem(self.PC)).value
            self.PC += 1
            tmp = self.PC
            self.PC += disp
        else:
            self.PC += 1

    def LDA(self, x):
        self.A = x
        self.X_ZN(self.A)
        return x

    def LDX(self, x):
        self.X = x
        self.X_ZN(self.X)
        return x

    def LDY(self, x):
        self.Y = x
        self.X_ZN(self.Y)
        return x

    def AND(self, x):
        self.A &= x
        self.X_ZN(self.A)
        return x

    def BIT(self, x):
        self.P &= ~(Z_FLAG|V_FLAG|N_FLAG)
        self.P |= self.ZNTable[x&self.A]&Z_FLAG
        self.P |= x&(V_FLAG|N_FLAG)
        return x

    def EOR(self, x):
        self.A ^= x
        self.X_ZN(self.A)
        return x

    def ORA(self, x):
        self.A |= x
        self.X_ZN(self.A)
        return x

    def ADC(self, x):
        l = self.A+x+(self.P&1)
        self.P &= ~(Z_FLAG|C_FLAG|N_FLAG|B_FLAG)
        self.P |= ((((self.A^x)&0x80)^0x80)&((self.A^l)&0x80))>>1
        self.P |= (l>>8)&C_FLAG
        self.A = l & 0xFF
        self.X_ZNT(self.A)
        return x

    def SBC(self, x):
        l = self.A-x-((self.P&1)^1)
        self.P &= ~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG)
        self.P |= ((self.A^l)&(self.A^x)&0x80)>>1
        self.P |= ((l>>8)&C_FLAG)^C_FLAG
        self.A = l & 0xFF
        self.X_ZNT(self.A)
        return x

    def CMPL(self, a1, a2):
        t = a1 - a2
        self.X_ZN(t&0xFF)
        self.P &= ~C_FLAG
        self.P |= ((t>>8)&C_FLAG)^C_FLAG

    def AXS(self, x):
        t = (self.A&self.X)-x
        self.X_ZN(t&0xFF)
        self.P &= ~C_FLAG
        self.P |= ((t>>8)&C_FLAG)^C_FLAG
        self.X = t & 0xFF
        return x

    def CMP(self, x):
        self.CMPL(self.A, x)
        return x

    def CPX(self, x):
        self.CMPL(self.X, x)
        return x

    def CPY(self, x):
        self.CMPL(self.Y, x)
        return x

    def DEC(self, x):
        x -= 1
        x &= 0xFF
        self.X_ZN(x)
        return x

    def INC(self, x):
        x += 1
        x &= 0xFF
        self.X_ZN(x)
        return x

    def ASL(self, x):
        self.P &= ~C_FLAG
        self.P |= x>>7
        x <<= 1
        x &= 0xFF
        self.X_ZN(x)
        return x

    def LSR(self, x):
        self.P &= ~(C_FLAG|N_FLAG|Z_FLAG)
        self.P |= x&1
        x >>= 1
        self.X_ZNT(x)
        return x

    def LSRA(self, x):
        self.P &= ~(C_FLAG|N_FLAG|Z_FLAG)
        self.P |= self.A&1
        self.A >> 1
        self.X_ZNT(self.A)
        return x

    def ROL(self, x):
        l = x>>7
        x <<= 1
        x &= 0xFF
        x |= self.P&C_FLAG
        self.P &= ~(Z_FLAG|N_FLAG|C_FLAG)
        self.P |= l
        self.X_ZNT(x)
        return x

    def ROR(self, x):
        l = x&1
        x >>= 1
        x |= (self.P&C_FLAG)<<7
        self.P &= ~(Z_FLAG|N_FLAG|C_FLAG)
        self.P |= 1
        self.X_ZNT(x)
        return x

    def GetAB(self):
        target = self.RdMem(self.PC)
        self.PC += 1
        target |= self.RdMem(self.PC) << 8
        self.PC += 1
        return target

    def GetABIRD(self, i):
        tmp = self.GetAB()
        target = tmp
        target += i
        if (target^tmp)&0x100:
            target &= 0xFFFF
            self.RdMem(target^0x100)
        return target

    def GetABIWR(self, i):
        rt = self.GetAB()
        target = rt
        target += i
        target &= 0xFFFF
        self.RdMem((target&0x00FF)|(rt&0xFF00))
        return target

    def GetZP(self):
        target = self.RdMem(self.PC)
        self.PC += 1
        return target

    def GetZPI(self, i):
        target = i + self.RdMem(self.PC)
        self.PC += 1
        return target

    def GetIX(self):
        tmp = self.RdMem(self.PC)
        self.PC += 1
        tmp += self.X
        target = self.RdRAM(tmp)
        tmp += 1
        target |= self.RdRAM(tmp) << 8
        return target

    def GetIYRD(self):
        tmp = self.RdMem(self.PC)
        self.PC += 1
        rt = self.RdRAM(tmp)
        tmp += 1
        rt |= self.RdRAM(tmp) << 8
        target = rt
        target += self.Y
        if (target^rt)&0x100:
            target &= 0xFFFF
            self.RdMem(target^0x100)
        return target

    def GetIYWR(self):
        tmp = self.RdMem(self.PC)
        self.PC += 1
        rt = self.RdRAM(tmp)
        tmp += 1
        rt |= self.RdRAM(tmp) << 8
        target = rt
        target += self.Y
        target &= 0xFFFF
        self.RdMem((target&0x00FF)|(rt&0xFF00))
        return target

    def RMW_A(self, op):
        self.A = op(self.A)

    def RMW_AB(self, op1, op2=None):
        A = self.GetAB()
        x = self.RdMem(A)
        self.WrMem(A, x)
        x = op1(x)
        if op2:
            x = op2(x)
        self.WrMem(A, x)

    def RMW_ABI(self, reg, op):
        A = self.GetABIWR(reg)
        x = self.RdMem(A)
        self.WrMem(A, x)
        x = op(x)
        self.WrMem(A, x)

    def RMW_ABX(self, op):
        self.RMW_ABI(self.X, op)

    def RMW_ABY(self, op):
        self.RMW_ABI(self.Y, op)

    def RMW_IX(self, op):
        A = self.GetIX()
        x = self.RdMem(A)
        self.WrMem(A, x)
        x = op(x)
        self.WrMem(A, x)

    def RMW_IY(self, op):
        A = self.GetIYWR()
        x = self.RdMem(A)
        self.WrMem(A, x)
        x = op(x)
        self.WrMem(A, x)

    def RMW_ZP(self, op1, op2=None):
        A = self.GetZP()
        x = self.RdRAM(A)
        x = op1(x)
        if op2:
            x = op2(x)
        self.WrRAM(A, x)

    def RMW_ZPX(self, op):
        A = self.GetZPI(self.X)
        x = self.RdRAM(A)
        x = op(x)
        self.WrRAM(A, x)

    def LD_IM(self, op):
        x = self.RdMem(self.PC)
        self.PC += 1
        x = op(x)

    def LD_ZP(self, op):
        A = self.GetZP()
        x = self.RdRAM(A)
        x = op(x)

    def LD_ZPX(self, op):
        A = self.GetZPI(self.X)
        x = self.RdRAM(A)
        x = op(x)

    def LD_ZPY(self, op):
        A = self.GetZPI(self.Y)
        x = self.RdRAM(A)
        x = op(x)

    def LD_AB(self, op):
        A = self.GetAB()
        x = self.RdMem(A)
        x = op(x)

    def LD_ABI(self, reg, op):
        A = self.GetABIRD(reg)
        x = self.RdMem(A)
        x = op(x)

    def LD_ABX(self, op):
        self.LD_ABI(self.X, op)

    def LD_ABY(self, op):
        self.LD_ABI(self.Y, op)

    def LD_IX(self, op):
        A = self.GetIX()
        x = self.RdMem(A)
        x = op(x)

    def LD_IY(self, op):
        A = self.GetIYRD()
        x = self.RdMem(A)
        x = op(x)

    def ST_ZP(self, r):
        A = self.GetZP()
        self.WrRAM(A, r)

    def ST_ZPX(self, r):
        A = self.GetZPI(self.X)
        self.WrRAM(A, r)

    def ST_ZPY(self, r):
        A = self.GetZPI(self.Y)
        self.WrRAM(self.A, r)

    def ST_AB(self, r):
        A = self.GetAB()
        self.WrMem(A, r)

    def ST_ABI(self, reg, r):
        A = self.GetABIWR(reg)
        self.WrMem(A, r)

    def ST_ABX(self, r):
        self.ST_ABI(self.X, r)

    def ST_ABY(self, r):
        self.ST_ABI(self.Y, r)

    def ST_IX(self, r):
        A = self.GetIX()
        self.WrMem(A, r)

    def ST_IY(self, r):
        A = self.GetIYWR()
        self.WrMem(A, r)

    def relative(self, addr):
        a = self.RdMem(addr+1)
        if a & 0x80:
            a = addr-((a-1)^0xFF)
        else:
            a += addr
        return a+2

    def absolute(self, addr):
        a = self.RdMem(addr+1) | self.RdMem(addr+2) << 8
        return a

    def zpIndex(self, addr, i):
        a = (self.RdMem(addr+1)+i)&0xFF
        return a

    def indirectX(self, addr):
        a = (self.RdMem(addr+1)+self.X)&0xFF
        a = self.RdMem(a) | self.RdMem((a+1)&0xFF) << 8
        return a

    def indirectY(self, addr):
        a = self.RdMem(self.RdMem(addr+1)) | self.RdMem((self.RdMem(addr+1)+1)&0xFF) << 8
        a += self.Y
        return a

    def setIRQ(self, addr):
        self.IRQ_PC = addr

    def opcode_00(self, prefix, pc):
        self.PC += 1
        self.PUSH(self.PC>>8)
        self.PUSH(self.PC)
        self.PUSH(self.P|U_FLAG|B_FLAG)
        self.P |= I_FLAG
        # self.PC = 0x0350  # 重启
        print(prefix, 'BRK @ 强制暂停')
        raise Exception('BRK') # 使程序退出

    # odd, 1-byte opcodes
    def opcode_08(self, prefix, pc):
        self.PUSH(self.P|U_FLAG|B_FLAG)
        self.print(prefix, 'PHP @ 处理器状态压入堆栈')
    def opcode_0A(self, prefix, pc):
        self.RMW_A(self.ASL)
        self.print(prefix, 'ASL @ 左移')
    def opcode_18(self, prefix, pc):
        self.P &= ~C_FLAG
        self.print(prefix, 'CLC @ 清进位标志')
    def opcode_28(self, prefix, pc):
        self.P = self.POP()
        self.print(prefix, 'PLP @ 堆栈弹回处理器状态')
    def opcode_2A(self, prefix, pc):
        self.RMW_A(self.ROL)
        self.print(prefix, 'ROL @ 循环左移')
    def opcode_38(self, prefix, pc):
        self.P |= C_FLAG
        self.print(prefix, 'SEC @ 置进位标志')
    def opcode_40(self, prefix, pc):
        self.P = self.POP()
        self.PC = self.POP()
        self.PC |= self.POP()<<8
        self.print(prefix, 'RTI @ 中断返回')
        self.print_IRQ_layers = None
        self.count_stack.pop()
        if not self.count_stack:
            raise Exception('count_stack is void')
    def opcode_48(self, prefix, pc):
        self.PUSH(self.A)
        self.print(prefix, 'PHA @ 累加器压入堆栈')
    def opcode_4A(self, prefix, pc):
        self.RMW_A(self.LSR)
        self.print(prefix, 'LSR @ 右移')
    def opcode_58(self, prefix, pc):
        self.P &= ~I_FLAG
        self.print(prefix, 'CLI @ 清中断禁止位')
    def opcode_60(self, prefix, pc):
        self.PC = self.POP()
        self.PC |= self.POP() << 8
        self.PC += 1
        self.print(prefix, 'RTS @ 子程序返回')
        self.count_stack.pop()
        if not self.count_stack:
            raise Exception('count_stack is void')
        self.print_layers += 1
        if self.print_IRQ_layers is not None:
            self.print_IRQ_layers += 1
    def opcode_68(self, prefix, pc):
        self.A = self.POP()
        self.X_ZN(self.A)
        self.print(prefix, 'PLA @ 堆栈弹回累加器')
    def opcode_6A(self, prefix, pc):
        self.RMW_A(self.ROR)
        self.print(prefix, 'ROR @ 循环右移')
    def opcode_78(self, prefix, pc):
        self.P |= I_FLAG
        self.print(prefix, 'SEI @ 置中断禁止位')
    def opcode_88(self, prefix, pc):
        self.Y -= 1
        self.X &= 0xFF
        self.X_ZN(self.Y)
        self.print(prefix, 'DEY @ 变址寄存器Y减1')
    def opcode_8A(self, prefix, pc):
        self.A = self.X
        self.X_ZN(self.A)
        self.print(prefix, 'TXA @ 变址寄存器X送累加器')
    def opcode_98(self, prefix, pc):
        self.A = self.Y
        self.X_ZN(self.A)
        self.print(prefix, 'TYA @ 变址寄存器Y送累加器')
    def opcode_9A(self, prefix, pc):
        self.S = self.X
        self.print(prefix, 'TXS @ 变址寄存器X送栈指针')
    def opcode_A8(self, prefix, pc):
        self.Y = self.A
        self.X_ZN(self.A)
        self.print(prefix, 'TAY @ 累加器送变址寄存器Y')
    def opcode_AA(self, prefix, pc):
        self.X = self.A
        self.X_ZN(self.A)
        self.print(prefix, 'TAX @ 累加器送变址寄存器X')
    def opcode_B8(self, prefix, pc):
        self.P &= ~V_FLAG
        self.print(prefix, 'CLV @ 清溢出标志')
    def opcode_BA(self, prefix, pc):
        self.X = self.S
        self.X_ZN(self.X)
        self.print(prefix, 'TSX @ 栈指针送变址寄存器X')
    def opcode_C8(self, prefix, pc):
        self.Y += 1
        self.Y &= 0xFF
        self.X_ZN(self.Y)
        self.print(prefix, 'INY @ 变址寄存器Y加1')
    def opcode_CA(self, prefix, pc):
        self.X -= 1
        self.X &= 0xFF
        self.X_ZN(self.X)
        self.print(prefix, 'DEX @ 变址寄存器X减1')
    def opcode_D8(self, prefix, pc):
        self.P &= ~D_FLAG
        self.print(prefix, 'CLD @ 清十进制方式')
    def opcode_E8(self, prefix, pc):
        self.X += 1
        self.X &= 0xFF
        self.X_ZN(self.X)
        self.print(prefix, 'INX @ 变址寄存器X加1')
    def opcode_EA(self, prefix, pc):
        pass
        self.print(prefix, 'NOP @ 空操作')
        self.count_stack[-1] -= 1  # NOP不计算次数，否则容易超出最大值
    def opcode_F8(self, prefix, pc):
        self.P |= D_FLAG
        self.print(prefix, 'SED @ 置十进制方式')

    # (Indirect,X)
    def opcode_01(self, prefix, pc):
        self.LD_IX(self.ORA)
        tmp = self.indirectX(pc)
        self.print(prefix, 'ORA ($%02X,X) @ $%04X = #$%02X @ 逻辑或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_21(self, prefix, pc):
        self.LD_IX(self.AND)
        tmp = self.indirectX(pc)
        self.print(prefix, 'AND ($%02X,X) @ $%04X = #$%02X @ 逻辑与' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_41(self, prefix, pc):
        self.LD_IX(self.EOR)
        tmp = self.indirectX(pc)
        self.print(prefix, 'EOR ($%02X,X) @ $%04X = #$%02X @ 逻辑异或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_61(self, prefix, pc):
        self.LD_IX(self.ADC)
        tmp = self.indirectX(pc)
        self.print(prefix, 'ADC ($%02X,X) @ $%04X = #$%02X @ 带进位加' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_81(self, prefix, pc):
        self.ST_IX(self.A)
        tmp = self.indirectX(pc)
        self.print(prefix, 'STA ($%02X,X) @ $%04X = #$%02X @ 存累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_A1(self, prefix, pc):
        self.LD_IX(self.LDA)
        tmp = self.indirectX(pc)
        self.print(prefix, 'LDA ($%02X,X) @ $%04X = #$%02X @ 送累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_C1(self, prefix, pc):
        self.LD_IX(self.CMP)
        tmp = self.indirectX(pc)
        self.print(prefix, 'CMP ($%02X,X) @ $%04X = #$%02X @ 累加器与存储器比较' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_E1(self, prefix, pc):
        self.LD_IX(self.SBC)
        tmp = self.indirectX(pc)
        self.print(prefix, 'SBC ($%02X,X) @ $%04X = #$%02X @ 带借位的减法' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))

    # Zero Page
    def opcode_05(self, prefix, pc):
        self.LD_ZP(self.ORA)
        self.print(prefix, 'ORA $%02X = #$%02X @ 逻辑或' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_06(self, prefix, pc):
        self.RMW_ZP(self.ASL)
        self.print(prefix, 'ASL $%02X = #$%02X @ 左移' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_24(self, prefix, pc):
        self.LD_ZP(self.BIT)
        self.print(prefix, 'BIT $%02X = #$%02X @ 位测试' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_25(self, prefix, pc):
        self.LD_ZP(self.AND)
        self.print(prefix, 'AND $%02X = #$%02X @ 逻辑与' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_26(self, prefix, pc):
        self.RMW_ZP(self.ROL)
        self.print(prefix, 'ROL $%02X = #$%02X @ 循环左移' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_45(self, prefix, pc):
        self.LD_ZP(self.EOR)
        self.print(prefix, 'EOR $%02X = #$%02X @ 逻辑异或' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_46(self, prefix, pc):
        self.RMW_ZP(self.LSR)
        self.print(prefix, 'LSR $%02X = #$%02X @ 右移' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_65(self, prefix, pc):
        self.LD_ZP(self.ADC)
        self.print(prefix, 'ADC $%02X = #$%02X @ 带进位加' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_66(self, prefix, pc):
        self.RMW_ZP(self.ROR)
        self.print(prefix, 'ROR $%02X = #$%02X @ 循环右移' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_84(self, prefix, pc):
        self.ST_ZP(self.Y)
        self.print(prefix, 'STY $%02X = #$%02X @ 存变址寄存器Y' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_85(self, prefix, pc):
        self.ST_ZP(self.A)
        self.print(prefix, 'STA $%02X = #$%02X @ 存累加器' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_86(self, prefix, pc):
        self.ST_ZP(self.X)
        self.print(prefix, 'STX $%02X = #$%02X @ 存变址寄存器X' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_A4(self, prefix, pc):
        self.LD_ZP(self.LDY)
        self.print(prefix, 'LDY $%02X = #$%02X @ 送变址寄存器Y' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_A5(self, prefix, pc):
        self.LD_ZP(self.LDA)
        self.print(prefix, 'LDA $%02X = #$%02X @ 送累加器' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_A6(self, prefix, pc):
        self.LD_ZP(self.LDX)
        self.print(prefix, 'LDX $%02X = #$%02X @ 送变址寄存器X' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_C4(self, prefix, pc):
        self.LD_ZP(self.CPY)
        self.print(prefix, 'CPY $%02X = #$%02X @ 变址寄存器Y与存储器比较' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_C5(self, prefix, pc):
        self.LD_ZP(self.CMP)
        self.print(prefix, 'CMP $%02X = #$%02X @ 累加器与存储器比较' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_C6(self, prefix, pc):
        self.RMW_ZP(self.DEC)
        self.print(prefix, 'DEC $%02X = #$%02X @ 存储器减1' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_E4(self, prefix, pc):
        self.LD_ZP(self.CPX)
        self.print(prefix, 'CPX $%02X = #$%02X @ 变址寄存器X与存储寄存器比较' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_E5(self, prefix, pc):
        self.LD_ZP(self.SBC)
        self.print(prefix, 'SBC $%02X = #$%02X @ 带借位的减法' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))
    def opcode_E6(self, prefix, pc):
        self.RMW_ZP(self.INC)
        self.print(prefix, 'INC $%02X = #$%02X @ 存储器加1' % (self.RdMem(pc+1, direct=True), self.RdMem(self.RdMem(pc+1, direct=True), direct=True)))

    # #Immediate
    def opcode_09(self, prefix, pc):
        self.LD_IM(self.ORA)
        self.print(prefix, 'ORA #$%02X @ 逻辑或' % (self.RdMem(pc+1, direct=True)))
    def opcode_29(self, prefix, pc):
        self.LD_IM(self.AND)
        self.print(prefix, 'AND #$%02X @ 逻辑与' % (self.RdMem(pc+1, direct=True)))
    def opcode_49(self, prefix, pc):
        self.LD_IM(self.EOR)
        self.print(prefix, 'EOR #$%02X @ 逻辑异或' % (self.RdMem(pc+1, direct=True)))
    def opcode_69(self, prefix, pc):
        self.LD_IM(self.ADC)
        self.print(prefix, 'ADC #$%02X @ 带进位加' % (self.RdMem(pc+1, direct=True)))
    def opcode_A0(self, prefix, pc):
        self.LD_IM(self.LDY)
        self.print(prefix, 'LDY #$%02X @ 送变址寄存器Y' % (self.RdMem(pc+1, direct=True)))
    def opcode_A2(self, prefix, pc):
        self.LD_IM(self.LDX)
        self.print(prefix, 'LDX #$%02X @ 送变址寄存器X' % (self.RdMem(pc+1, direct=True)))
    def opcode_A9(self, prefix, pc):
        self.LD_IM(self.LDA)
        self.print(prefix, 'LDA #$%02X @ 送累加器' % (self.RdMem(pc+1, direct=True)))
    def opcode_C0(self, prefix, pc):
        self.LD_IM(self.CPY)
        self.print(prefix, 'CPY #$%02X @ 变址寄存器Y与存储器比较' % (self.RdMem(pc+1, direct=True)))
    def opcode_C9(self, prefix, pc):
        self.LD_IM(self.CMP)
        self.print(prefix, 'CMP #$%02X @ 累加器与存储器比较' % (self.RdMem(pc+1, direct=True)))
    def opcode_E0(self, prefix, pc):
        self.LD_IM(self.CPX)
        self.print(prefix, 'CPX #$%02X @ 变址寄存器X与存储寄存器比较' % (self.RdMem(pc+1, direct=True)))
    def opcode_E9(self, prefix, pc):
        self.LD_IM(self.SBC)
        self.print(prefix, 'SBC #$%02X @ 带借位的减法' % (self.RdMem(pc+1, direct=True)))

    # Absolute
    def opcode_0D(self, prefix, pc):
        self.LD_AB(self.ORA)
        tmp = self.absolute(pc)
        self.print(prefix, 'ORA $%04X = #$%02X @ 逻辑或' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_0E(self, prefix, pc):
        self.RMW_AB(self.ASL)
        tmp = self.absolute(pc)
        self.print(prefix, 'ASL $%04X = #$%02X @ 左移' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_2C(self, prefix, pc):
        self.LD_AB(self.BIT)
        tmp = self.absolute(pc)
        self.print(prefix, 'BIT $%04X = #$%02X @ 位测试' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_2D(self, prefix, pc):
        self.LD_AB(self.AND)
        tmp = self.absolute(pc)
        self.print(prefix, 'AND $%04X = #$%02X @ 逻辑与' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_2E(self, prefix, pc):
        self.RMW_AB(self.ROL)
        tmp = self.absolute(pc)
        self.print(prefix, 'ROL $%04X = #$%02X @ 循环左移' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_4D(self, prefix, pc):
        self.LD_AB(self.EOR)
        tmp = self.absolute(pc)
        self.print(prefix, 'EOR $%04X = #$%02X @ 逻辑异或' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_4E(self, prefix, pc):
        self.RMW_AB(self.LSR)
        tmp = self.absolute(pc)
        self.print(prefix, 'LSR $%04X = #$%02X @ 右移' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_6D(self, prefix, pc):
        self.LD_AB(self.ADC)
        tmp = self.absolute(pc)
        self.print(prefix, 'ADC $%04X = #$%02X @ 带进位加' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_6E(self, prefix, pc):
        self.RMW_AB(self.ROR)
        tmp = self.absolute(pc)
        self.print(prefix, 'ROR $%04X = #$%02X @ 循环右移' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_8C(self, prefix, pc):
        self.ST_AB(self.Y)
        tmp = self.absolute(pc)
        self.print(prefix, 'STY $%04X = #$%02X @ 存变址寄存器Y' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_8D(self, prefix, pc):
        self.ST_AB(self.A)
        tmp = self.absolute(pc)
        self.print(prefix, 'STA $%04X = #$%02X @ 存累加器' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_8E(self, prefix, pc):
        self.ST_AB(self.X)
        tmp = self.absolute(pc)
        self.print(prefix, 'STX $%04X = #$%02X @ 存变址寄存器X' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_AC(self, prefix, pc):
        self.LD_AB(self.LDY)
        tmp = self.absolute(pc)
        self.print(prefix, 'LDY $%04X = #$%02X @ 送变址寄存器Y' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_AD(self, prefix, pc):
        self.LD_AB(self.LDA)
        tmp = self.absolute(pc)
        self.print(prefix, 'LDA $%04X = #$%02X @ 送累加器' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_AE(self, prefix, pc):
        self.LD_AB(self.LDX)
        tmp = self.absolute(pc)
        self.print(prefix, 'LDX $%04X = #$%02X @ 送变址寄存器X' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_CC(self, prefix, pc):
        self.LD_AB(self.CPY)
        tmp = self.absolute(pc)
        self.print(prefix, 'CPY $%04X = #$%02X @ 变址寄存器Y与存储器比较' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_CD(self, prefix, pc):
        self.LD_AB(self.CMP)
        tmp = self.absolute(pc)
        self.print(prefix, 'CMP $%04X = #$%02X @ 累加器与存储器比较' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_CE(self, prefix, pc):
        self.RMW_AB(self.DEC)
        tmp = self.absolute(pc)
        self.print(prefix, 'DEC $%04X = #$%02X @ 存储器减1' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_EC(self, prefix, pc):
        self.LD_AB(self.CPX)
        tmp = self.absolute(pc)
        self.print(prefix, 'CPX $%04X = #$%02X @ 变址寄存器X与存储寄存器比较' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_ED(self, prefix, pc):
        self.LD_AB(self.SBC)
        tmp = self.absolute(pc)
        self.print(prefix, 'SBC $%04X = #$%02X @ 带借位的减法' % (tmp, self.RdMem(tmp, direct=True)))
    def opcode_EE(self, prefix, pc):
        self.RMW_AB(self.INC)
        tmp = self.absolute(pc)
        self.print(prefix, 'INC $%04X = #$%02X @ 存储器加1' % (tmp, self.RdMem(tmp, direct=True)))

    # branches
    def opcode_10(self, prefix, pc):
        self.JR(not(self.P&N_FLAG))
        tmp = self.relative(pc)
        self.print(prefix, 'BPL $%04X @ 结果为正分支' % (tmp))
    def opcode_30(self, prefix, pc):
        self.JR(self.P&N_FLAG)
        tmp = self.relative(pc)
        self.print(prefix, 'BMI $%04X @ 结果为负分支' % (tmp))
    def opcode_50(self, prefix, pc):
        self.JR(not (self.P&V_FLAG))
        tmp = self.relative(pc)
        self.print(prefix, 'BVC $%04X @ 溢出为0分支' % (tmp))
    def opcode_70(self, prefix, pc):
        self.JR(self.P&V_FLAG)
        tmp = self.relative(pc)
        self.print(prefix, 'BVS $%04X @ 溢出为1分支' % (tmp))
    def opcode_90(self, prefix, pc):
        self.JR(not (self.P&C_FLAG))
        tmp = self.relative(pc)
        self.print(prefix, 'BCC $%04X @ 进位为0分支' % (tmp))
    def opcode_B0(self, prefix, pc):
        self.JR(self.P&C_FLAG)
        tmp = self.relative(pc)
        self.print(prefix, 'BCS $%04X @ 进位为“1”分支' % (tmp))
    def opcode_D0(self, prefix, pc):
        self.JR(not (self.P&Z_FLAG))
        tmp = self.relative(pc)
        self.print(prefix, 'BNE $%04X @ 结果不为0分支' % (tmp))
    def opcode_F0(self, prefix, pc):
        self.JR(self.P&Z_FLAG)
        tmp = self.relative(pc)
        self.print(prefix, 'BEQ $%04X @ 结果为0分支' % (tmp))

    # (Indirect), Y
    def opcode_11(self, prefix, pc):
        self.LD_IY(self.ORA)
        tmp = self.indirectY(pc)
        self.print(prefix, 'ORA ($%02X),Y @ $%04X = #$%02X @ 逻辑或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_31(self, prefix, pc):
        self.LD_IY(self.AND)
        tmp = self.indirectY(pc)
        self.print(prefix, 'AND ($%02X),Y @ $%04X = #$%02X @ 逻辑与' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_51(self, prefix, pc):
        self.LD_IY(self.EOR)
        tmp = self.indirectY(pc)
        self.print(prefix, 'EOR ($%02X),Y @ $%04X = #$%02X @ 逻辑异或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_71(self, prefix, pc):
        self.LD_IY(self.ADC)
        tmp = self.indirectY(pc)
        self.print(prefix, 'ADC ($%02X),Y @ $%04X = #$%02X @ 带进位加' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_91(self, prefix, pc):
        self.ST_IY(self.A)
        tmp = self.indirectY(pc)
        self.print(prefix, 'STA ($%02X),Y @ $%04X = #$%02X @ 存累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_B1(self, prefix, pc):
        self.LD_IY(self.LDA)
        tmp = self.indirectY(pc)
        self.print(prefix, 'LDA ($%02X),Y @ $%04X = #$%02X @ 送累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_D1(self, prefix, pc):
        self.LD_IY(self.CMP)
        tmp = self.indirectY(pc)
        self.print(prefix, 'CMP ($%02X),Y @ $%04X = #$%02X @ 累加器与存储器比较' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_F1(self, prefix, pc):
        self.LD_IY(self.SBC)
        tmp = self.indirectY(pc)
        self.print(prefix, 'SBC ($%02X),Y @ $%04X = #$%02X @ 带借位的减法' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))

    # Zero Page, X
    def opcode_15(self, prefix, pc):
        self.LD_ZPX(self.ORA)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'ORA $%02X,X @ $%04X = #$%02X @ 逻辑或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_16(self, prefix, pc):
        self.RMW_ZPX(self.ASL)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'ASL $%02X,X @ $%04X = #$%02X @ 左移' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_35(self, prefix, pc):
        self.LD_ZPX(self.AND)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'AND $%02X,X @ $%04X = #$%02X @ 逻辑与' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_36(self, prefix, pc):
        self.RMW_ZPX(self.ROL)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'ROL $%02X,X @ $%04X = #$%02X @ 循环左移' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_55(self, prefix, pc):
        self.LD_ZPX(self.EOR)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'EOR $%02X,X @ $%04X = #$%02X @ 逻辑异或' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_56(self, prefix, pc):
        self.RMW_ZPX(self.LSR)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'LSR $%02X,X @ $%04X = #$%02X @ 右移' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_75(self, prefix, pc):
        self.LD_ZPX(self.ADC)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'ADC $%02X,X @ $%04X = #$%02X @ 带进位加' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_76(self, prefix, pc):
        self.RMW_ZPX(self.ROR)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'ROR $%02X,X @ $%04X = #$%02X @ 循环右移' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_94(self, prefix, pc):
        self.ST_ZPX(self.Y)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'STY $%02X,X @ $%04X = #$%02X @ 存变址寄存器Y' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_95(self, prefix, pc):
        self.ST_ZPX(self.A)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'STA $%02X,X @ $%04X = #$%02X @ 存累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_B4(self, prefix, pc):
        self.LD_ZPX(self.LDY)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'LDY $%02X,X @ $%04X = #$%02X @ 送变址寄存器Y' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_B5(self, prefix, pc):
        self.LD_ZPX(self.LDA)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'LDA $%02X,X @ $%04X = #$%02X @ 送累加器' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_D5(self, prefix, pc):
        self.LD_ZPX(self.CMP)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'CMP $%02X,X @ $%04X = #$%02X @ 累加器与存储器比较' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_D6(self, prefix, pc):
        self.RMW_ZPX(self.DEC)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'DEC $%02X,X @ $%04X = #$%02X @ 存储器减1' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_F5(self, prefix, pc):
        self.LD_ZPX(self.SBC)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'SBC $%02X,X @ $%04X = #$%02X @ 带借位的减法' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_F6(self, prefix, pc):
        self.RMW_ZPX(self.INC)
        tmp = self.zpIndex(pc, self.X)
        self.print(prefix, 'INC $%02X,X @ $%04X = #$%02X @ 存储器加1' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))

    # Absolute, Y
    def opcode_19(self, prefix, pc):
        self.LD_ABY(self.ORA)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'ORA $%04X,Y @ $%04X = #$%02X @ 逻辑或' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_39(self, prefix, pc):
        self.LD_ABY(self.AND)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'AND $%04X,Y @ $%04X = #$%02X @ 逻辑与' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_59(self, prefix, pc):
        self.LD_ABY(self.EOR)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'EOR $%04X,Y @ $%04X = #$%02X @ 逻辑异或' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_79(self, prefix, pc):
        self.LD_ABY(self.ADC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'ADC $%04X,Y @ $%04X = #$%02X @ 带进位加' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_99(self, prefix, pc):
        self.ST_ABY(self.A)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'STA $%04X,Y @ $%04X = #$%02X @ 存累加器' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_B9(self, prefix, pc):
        self.LD_ABY(self.LDA)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'LDA $%04X,Y @ $%04X = #$%02X @ 送累加器' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_BE(self, prefix, pc):
        self.LD_ABY(self.LDX)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'LDX $%04X,Y @ $%04X = #$%02X @ 送变址寄存器X' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_D9(self, prefix, pc):
        self.LD_ABY(self.CMP)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'CMP $%04X,Y @ $%04X = #$%02X @ 累加器与存储器比较' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_F9(self, prefix, pc):
        self.LD_ABY(self.SBC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.Y
        self.print(prefix, 'SBC $%04X,Y @ $%04X = #$%02X @ 带借位的减法' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))

    # Absolute, X
    def opcode_1D(self, prefix, pc):
        self.LD_ABX(self.ORA)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'ORA $%04X,X @ $%04X = #$%02X @ 逻辑或' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_1E(self, prefix, pc):
        self.RMW_ABX(self.ASL)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'ASL $%04X,X @ $%04X = #$%02X @ 左移' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_3D(self, prefix, pc):
        self.LD_ABX(self.AND)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'AND $%04X,X @ $%04X = #$%02X @ 逻辑与' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_3E(self, prefix, pc):
        self.RMW_ABX(self.ROL)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'ROL $%04X,X @ $%04X = #$%02X @ 循环左移' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_5D(self, prefix, pc):
        self.LD_ABX(self.EOR)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'EOR $%04X,X @ $%04X = #$%02X @ 逻辑异或' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_5E(self, prefix, pc):
        self.RMW_ABX(self.LSR)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'LSR $%04X,X @ $%04X = #$%02X @ 右移' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_7D(self, prefix, pc):
        self.LD_ABX(self.ADC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'ADC $%04X,X @ $%04X = #$%02X @ 带进位加' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_7E(self, prefix, pc):
        self.RMW_ABX(self.ROR)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'ROR $%04X,X @ $%04X = #$%02X @ 循环右移' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_9D(self, prefix, pc):
        self.ST_ABX(self.A)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'STA $%04X,X @ $%04X = #$%02X @ 存累加器' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_BC(self, prefix, pc):
        self.LD_ABX(self.LDY)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'LDY $%04X,X @ $%04X = #$%02X @ 送变址寄存器Y' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_BD(self, prefix, pc):
        self.LD_ABX(self.LDA)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'LDA $%04X,X @ $%04X = #$%02X @ 送累加器' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_DD(self, prefix, pc):
        self.LD_ABX(self.CMP)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'CMP $%04X,X @ $%04X = #$%02X @ 累加器与存储器比较' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_DE(self, prefix, pc):
        self.RMW_ABX(self.DEC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'DEC $%04X,X @ $%04X = #$%02X @ 存储器减1' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_FD(self, prefix, pc):
        self.LD_ABX(self.SBC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'SBC $%04X,X @ $%04X = #$%02X @ 带借位的减法' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))
    def opcode_FE(self, prefix, pc):
        self.RMW_ABX(self.INC)
        tmp = self.absolute(pc)
        tmp2 = tmp + self.X
        self.print(prefix, 'INC $%04X,X @ $%04X = #$%02X @ 存储器加1' % (tmp, tmp2, self.RdMem(tmp2, direct=True)))

    # jumps
    def opcode_20(self, prefix, pc):
        npc = self.RdMem(self.PC)
        self.PC += 1
        self.PUSH(self.PC >> 8)
        self.PUSH(self.PC)
        self.PC = self.RdMem(self.PC) << 8
        self.PC |= npc
        tmp = self.absolute(pc)
        self.print(prefix, 'JSR $%04X @ 转子$%08X' % (tmp, self.getPhysicalAddress(tmp)))
        self.count_stack.append(0)
        self.print_layers -= 1
        if self.print_IRQ_layers is not None:
            self.print_IRQ_layers -= 1
    def opcode_4C(self, prefix, pc):
        ptmp = self.PC
        npc = self.RdMem(ptmp)
        ptmp += 1
        npc |= self.RdMem(ptmp) << 8
        self.PC = npc
        tmp = self.absolute(pc)
        self.print(prefix, 'JMP $%04X @ 转移$%08X' % (tmp, self.getPhysicalAddress(tmp)))
    def opcode_6C(self, prefix, pc):
        tmp = self.GetAB()
        self.PC = self.RdMem(tmp)
        self.PC |= self.RdMem( ((tmp+1)&0x00FF) | (tmp&0xFF00))<<8
        tmp = self.absolute(pc)
        tmp2 = self.RdMem(tmp)|(self.RdMem(tmp+1)<<8)
        self.print(prefix, 'JMP ($%04X) = $%04X @ 转移$%08X' % (tmp, tmp2, self.getPhysicalAddress(tmp2)))

    # Zero Page, Y
    def opcode_96(self, prefix, pc):
        self.ST_ZPY(self.X)
        tmp = self.zpIndex(pc, self.Y)
        self.print(prefix, 'STX $%02X,Y @ $%04X = #$%02X @ 存变址寄存器X' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))
    def opcode_B6(self, prefix, pc):
        self.LD_ZPY(self.LDX)
        tmp = self.zpIndex(pc, self.Y)
        self.print(prefix, 'LDX $%02X,Y @ $%04X = #$%02X @ 送变址寄存器X' % (self.RdMem(pc+1, direct=True), tmp, self.RdMem(tmp, direct=True)))

    def opcode_unknown(self, prefix, pc):
        print(prefix)
        raise Exception('unknown opcode')
